#include "battery_ropeencoder_can.h"

Battery_Ropeencoder_can::Battery_Ropeencoder_can(DWORD dw_DeviceHandle, QObject *parent) : QObject(parent)
{

#ifdef NJLAKCAN
    canDevice = new NJLikeCanDevice();
#endif
#ifdef ZLGCAN
    canDevice = new ZLGCanDevice();
    this->dw_DeviceHandle = dw_DeviceHandle;
#endif

}

//打开CAN2口
bool Battery_Ropeencoder_can::CanOpenAndStart() {
    DWORD dwRel;

    #ifdef NJLAKCAN
        dw_DeviceHandle = canDevice->CanDeviceOpen( CAN_DEVICE_TYPE, dw_Index, nullptr );
        qDebug() << "ForkliftDrive dw_DeviceHandle" << dw_DeviceHandle;
        if ( dw_DeviceHandle == 0 ) { return false; }
    #endif

    CanInitConfig config;
    config.dwAccCode = 0;
    config.dwAccMask = 0xffffffff;
    config.nFilter = 0;         // 滤波方式(0表示未设置滤波功能,1表示双滤波,2表示单滤波)
    config.bMode = 0;           // 工作模式(0表示正常模式,1表示只听模式)
    config.nBtrType = 1;        // 位定时参数模式(1表示SJA1000,0表示LPC21XX)
    config.dwBtr[0] = dw_Btr0;  // BTR0   0014 -1M 0016-800K 001C-500K 011C-250K 031C-125K  041C-100K 091C-50K 181C-20K 311C-10K BFFF-5K
    config.dwBtr[1] = dw_Btr1;  // BTR1
    config.dwBtr[2] = 0;
    config.dwBtr[3] = 0;

    dwRel = canDevice->CanChannelStart( dw_DeviceHandle, CAN_DEVICE_TYPE, dw_Index, dw_Channel, &config );

    if ( dwRel != CAN_DEVICE_RESULT_OK ) {
        qDebug() << "battery can open error: " << dwRel;
        return false;
    }
    is_open_can = true;
    return true;
}

//关闭CAN口
bool Battery_Ropeencoder_can::CanStopAndClose() {
    if ( is_open_can ) {
        if ( canDevice->CanChannelStopDeviceClose( dw_DeviceHandle, CAN_DEVICE_TYPE, dw_Index, dw_Channel ) ) {
            is_open_can = false;
            qDebug() << "成功，CAN关闭";
            return true;
        }
    }
    return false;
    return false;
}

//接收CAN数据
bool Battery_Ropeencoder_can::CanRecviveData() {
    if (!is_open_can) { return false; }
    CanDataFrame vco[200];
    uint dwRel = static_cast< uint >( canDevice->CanChannelReceive( dw_DeviceHandle, CAN_DEVICE_TYPE, dw_Index, dw_Channel, vco, 200, 40 ) );

    if (dwRel <= 0) { return false; }
    for (ULONG i = 0; i < dwRel; i++) {
        QByteArray recv;
        for (int k = 0; k < vco[i].nDataLen; k++) { recv.append(static_cast<char>(vco[i].arryData[k])); }
        emit sigShowCanData(recv, "Recv2:" + QString::number(vco[i].uID, 16));  //发送打印static_cast<short int>
        //读取电池数据
        switch (vco[i].uID) {
        case 0x1E1:
            battery_data.total_vol = 0.1 * static_cast<uint16_t>((vco[i].arryData[0] << 8) + vco[i].arryData[1]);
            battery_data.total_cur = 0.1 * static_cast<uint16_t>((vco[i].arryData[2] << 8) + vco[i].arryData[3]) - 1000;
            battery_data.soc = 0.1 * static_cast<uint16_t>((vco[i].arryData[4] << 8) + vco[i].arryData[5]);
            break;
        case 0x352:
            battery_data.max_singel_vol = 0.001 * static_cast<uint16_t>((vco[i].arryData[0] << 8) + vco[i].arryData[1]);
            battery_data.max_singel_vol_num = static_cast<uint16_t>((vco[i].arryData[2] << 8) + vco[i].arryData[3]);
            battery_data.min_singel_vol = 0.001 * static_cast<uint16_t>((vco[i].arryData[4] << 8) + vco[i].arryData[5]);
            battery_data.min_singel_vol_num = static_cast<uint16_t>((vco[i].arryData[6] << 8) + vco[i].arryData[7]);
            break;
        case 0x353:
            battery_data.max_temp = static_cast<int8_t>(vco[i].arryData[0]) - 50;
            battery_data.max_temp_num = static_cast<uint16_t>((vco[i].arryData[1] << 8) + vco[i].arryData[2]);
            battery_data.min_temp = static_cast<int8_t>(vco[i].arryData[3]) - 50;
            battery_data.min_temp_num = static_cast<uint16_t>((vco[i].arryData[4] << 8) + vco[i].arryData[5]);
            break;
        case 0x1E4:
            battery_data.charge_relay_state = (vco[i].arryData[0] >> 5) & 0b1;
            battery_data.charge_state = static_cast<ChargeState>((vco[i].arryData[0] >> 6) & 0b11);
            break;
        }
        //读取拉绳编码器数据
//        if(vco[i].uID == 0X1BF ){
//            u_int32_t Ropeencoder= vco[i].arryData[0] + ( vco[i].arryData[1] << 8 ) + ( vco[i].arryData[2] << 16) + ( vco[i].arryData[3] << 24);
//            Ropeencoder_data.Ropeencoder_Height_Value = (( Ropeencoder * 0.014038 ) / 10 );
//            //          qDebug() << "拉绳编码器反馈高度为：" << Ropeencoder_data.Ropeencoder_Height_Value << endl;
//        }
    }
    return true;
}

//初始化CAN
void Battery_Ropeencoder_can::sltCanInit_1() {

    if (CanOpenAndStart()) {
        emit sigSendTips("正确，CAN2口设备打开成功");
    } else {
        emit sigSendTips("错误，CAN2口设备打开失败");
        return;
    }
    ULONG i = 0;
    CanDataFrame frames[20];
    Start_Ropeencoder_Read(frames[i++]);
    Can_Set_Ropeencoder_Rate(frames[i++]);
    CanSendData(frames, i);

    emit sigSendTips("提示，电池拉升编码器初始化完成！");
    Utility::delayMs(1000);  // 非阻塞延时执行
    QTimer *timer50ms = new QTimer();
    connect(timer50ms, SIGNAL(timeout()), this, SLOT(sltTimeOut()));
    timer50ms->start(50);
}

//发送CAN数据
void Battery_Ropeencoder_can::CanSendData(CanDataFrame* frames, ULONG i) {
    if (i == 0) return;
    if ( FRAMES_CNT >= i )
        canDevice->CanChannelSend( dw_DeviceHandle, CAN_DEVICE_TYPE, dw_Index, dw_Channel, frames, i );
    else {
        for ( ; i > FRAMES_CNT; i -= FRAMES_CNT )
            canDevice->CanChannelSend( dw_DeviceHandle, CAN_DEVICE_TYPE, dw_Index, dw_Channel, frames, FRAMES_CNT );
        if ( i > 0 ) canDevice->CanChannelSend( dw_DeviceHandle, CAN_DEVICE_TYPE, dw_Index, dw_Channel, frames + FRAMES_CNT, i );
    }
}

//定期获取数据
void Battery_Ropeencoder_can::RegularGetData() {
    ULONG i = 0;
    CanDataFrame frames[20];

    CanSendData(frames, i);
}

//定时发布
void Battery_Ropeencoder_can::sltTimeOut() {
    if (!is_open_can) { return; }
    //定期发送
    RegularGetData();

    //定期接收
    CanRecviveData();
}

//获取电池反馈数据
Battery_Ropeencoder_can::BatteryData_YJT Battery_Ropeencoder_can::getBatteryData() const
{
    return battery_data;
}

//获取拉绳编码器反馈数据
Battery_Ropeencoder_can::Ropeencoder_Kubler Battery_Ropeencoder_can::GetRopeencoderData() const
{
    return Ropeencoder_data;
}

//打开电池充电继电器-报文 160
void Battery_Ropeencoder_can::charge(bool enable) {
    CanDataFrame frames[1];
    frames[0].uID = 0x160;
    frames[0].nSendType = 0;
    frames[0].bRemoteFlag = 0;
    frames[0].bExternFlag = 0;
    frames[0].nDataLen = 1;
    frames[0].arryData[0] = enable ? 0x1 : 0x0;
    CanSendData(frames, 1);
}

//开始读取拉绳编码器的值
void Battery_Ropeencoder_can::Start_Ropeencoder_Read(CanDataFrame &frame) {
    frame.uID = 0x00;
    frame.nSendType = 0;
    frame.bRemoteFlag = 0;
    frame.bExternFlag = 0;
    frame.nDataLen = 2;
    frame.arryData[0] = 0x01;
    frame.arryData[1] = 0X00;
}

void Battery_Ropeencoder_can::Can_Set_Ropeencoder_Rate(CanDataFrame &frame)
{
    frame.uID = 0x063f;
    frame.nSendType = 0;
    frame.bRemoteFlag = 0;
    frame.bExternFlag = 0;
    frame.nDataLen = 8;
    for (int i = 0; i < 8; i++) { frame.arryData[i] = Ropeencoder_Rate[i]; }
}
